﻿using System;
using System.Collections.Generic;
using System.ComponentModel.Composition;
using System.Data;
using System.Linq;
using System.Text;
using Caliburn.Core.InversionOfControl;
using Caliburn.PresentationFramework;
using Caliburn.PresentationFramework.Filters;
using Caliburn.PresentationFramework.Invocation;
using Caliburn.PresentationFramework.RoutedMessaging;
using Caliburn.ShellFramework.Results;
using MTGenome.Framework;
using MTGenome.MTG;

namespace MTGenome.ViewModels
{
    [Singleton(typeof(SearchViewModel)), PartCreationPolicy(CreationPolicy.Shared)]
    public sealed class SearchViewModel : RescueBase
    {
        private readonly FilterViewModel _filter = null;
        private readonly CardDetailViewModel _cardDetail = null;
        private string _searchText = null;

        public SearchViewModel(FilterViewModel filter, CardDetailViewModel cardDetail)
        {
            _filter = filter;
            _cardDetail = cardDetail;
        }

        public QuickCardViewModel[] Results
        {
            get;
            set;
        }

        public string SearchText
        {
            get { return _searchText; }
            set { _searchText = value; NotifyOfPropertyChange(() => SearchText); }
        }

        public IEnumerable<IResult> Loaded()
        {
            yield return new FocusResult(this, "SearchText");
        }

        public IEnumerable<IResult> Search()
        {
            yield return Show.Busy();

            yield return new AsyncResult(() =>
                {
                    using (IDatabase database = IoC.Get<IDatabase>())
                    {
                        var query = database.Cards;

                        //Text filter
                        if (!string.IsNullOrEmpty(_searchText))
                        {
                            query = query.Where(c => c.Name != null && c.Name.Contains(_searchText));
                        }

                        //Color filter
                        if (!_filter.AnyColor)
                        {
                            query = query.Where(c => (c.Color & _filter.Color) == c.Color);
                            if (!_filter.Colorless)
                            {
                                query = query.Where(c => c.Color != Color.Colorless);
                            }
                        }

                        //Card type filter
                        if (!_filter.AnyType)
                        {
                            var where = PredicateBuilder.False<ICard>();
                            if (_filter.Artifacts)
                            {
                                where = where.Or(c => c.Type.Contains("Artifact"));
                            }
                            if (_filter.Creatures)
                            {
                                where = where.Or(c => c.Type.Contains("Creature"));
                            }
                            if (_filter.Lands)
                            {
                                where = where.Or(c => c.Type.Contains("Land"));
                            }
                            if (_filter.Enchantments)
                            {
                                where = where.Or(c => c.Type.Contains("Enchantment"));
                            }
                            if (_filter.Sorceries)
                            {
                                where = where.Or(c => c.Type.Contains("Sorcery"));
                            }
                            if (_filter.Instants)
                            {
                                where = where.Or(c => c.Type.Contains("Instant"));
                            }
                            if (_filter.Plainswalkers)
                            {
                                where = where.Or(c => c.Type.Contains("Plainswalker"));
                            }
                            query = query.Where(where);
                        }

                        if (!_filter.AnyExpansion)
                        {
                            var where = PredicateBuilder.True<ICard>();
                            foreach (var item in _filter.Expansions.Where(e => !e.IsChecked))
                            {
                                where = where.And(c => c.Expansion != item.ID);
                            }
                            query = query.Where(where);
                        }

                        query = query.OrderBy(c => c.Name).Take(50);

                        Results = query.AsEnumerable()
                            .Select(c => 
                            {
                                var card = IoC.Get<QuickCardViewModel>();
                                card.Card = c;
                                return card;
                            })
                            .ToArray();
                        if (Results.Length > 0)
                        {
                            Results[0].IsSelected = true;
                        }
                        else
                        {
                            _cardDetail.Card = null;
                        }
                        NotifyOfPropertyChange(() => Results);
                    }
                });

            yield return Show.NotBusy();
        }
    }
}
